﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Kooboo.Commerce;
using Kooboo.Web.Models;
using Kooboo.Web.Mvc;
using Kooboo.Commerce.Services;


namespace Kooboo.Web.Controllers
{
    public class CartController : ControllerBase
    {
        //
        // GET: /Cart/

        #region Index

        public ActionResult Index()
        {
            this.BindViewData();

            this.BindCartLinks();

            this.BindCartItems();

            return View(this.OpenCart());
        }

        [HttpPost]
        public ActionResult Index(List<CartItem> cartItems)
        {
            Dictionary<Int32, Int32> items = new Dictionary<int, int>();

            //update shopping cart
            String ids = this.Request["Id"];
            if (!String.IsNullOrEmpty(ids))
            {
                String[] array = ids.Split(',');
                foreach (var item in array)
                {
                    int id = 0, quantity = 0;
                    
                    String quantityVal = this.Request["Id_" + item + "_Quantity"];
                    if (!String.IsNullOrEmpty(quantityVal))
                    {
                        if (Int32.TryParse(item, out id) && Int32.TryParse(quantityVal, out quantity))
                        {
                            items.Add(id, quantity);
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }

            if (items.Count > 0)
            {
                var cartService = new CartService();
                foreach (var item in items)
                {
                    cartService.UpdateItemQuntity(item.Key, item.Value);
                }
            }


            this.BindViewData();

            this.BindCartLinks();

            this.BindCartItems();

            return View(this.OpenCart());
        }

        #endregion

        #region CartItem

        public ActionResult Add(int saleItemId, int amount)
        {
            // this.BindViewData();
            var service = new CartService();

            service.AddItem(saleItemId, amount);

            return this.Redirect(this.Url.Action<CartController>(m => m.Index()));

        }

        public ActionResult Remove(int id, int quantity)
        {
            var service = new CartService();
            service.RemoveItem(id, quantity);


            return this.Redirect(this.Url.Action<CartController>(m => m.Index()));
        }

        #endregion

        #region Checkout

        [Authorize(Roles = "Customer")]
        public ActionResult Checkout()
        {
            this.BindViewData();
            this.BindCartLinks();
            this.BindAdresses();

            var serviceClient = new CartService();
            //shipping information
            var shippingInfo = serviceClient.GetShippingInfo();
            this.BindShippingItems(shippingInfo.Shipping);
            this.BindShippingCountryItems(shippingInfo.Country);

            //payment information
            var paymentInfo = serviceClient.GetPaymentInfo();
            this.BindPaymentCountryItems(paymentInfo.InvoiceCountry);
            this.BindPaymentItmes(paymentInfo.Payment);

            this.ViewBag.Shipping = shippingInfo;
            this.ViewBag.Payment = paymentInfo;

            return View(new AddressInfo { Shipping = shippingInfo, Payment = paymentInfo });
        }

        [HttpPost]
        [Authorize(Roles = "Customer")]
        public ActionResult Checkout(ShippingInfo info, PaymentInfo paymentInfo)
        {
            var service = new CartService();
            //shipping address
            service.Update(info);
            //payment address
            bool sameAsShippingAddress = Request["SameAsShippingAddress"] == "on";
            if (sameAsShippingAddress)
            {
                paymentInfo.InvoiceFirstName = info.FirstName;
                paymentInfo.InvoiceLastName = info.LastName;
                paymentInfo.InvoicePhone = info.Phone;
                paymentInfo.InvoicePostcode = info.Postcode;
                paymentInfo.InvoiceState = info.State;
                paymentInfo.InvoiceAddress1 = info.Address1;
                paymentInfo.InvoiceAddress2 = info.Address2;
                paymentInfo.InvoiceCity = info.City;
                paymentInfo.InvoiceCountry = info.Country;
            }
            paymentInfo.UseInvoiceAddress = !sameAsShippingAddress;

            service.Update(paymentInfo);

            return Redirect(this.Url.Action<CartController>(m => m.Payment()));
        }

        #endregion

        #region Payment

        [Authorize(Roles = "Customer")]
        public ActionResult Payment()
        {
            this.BindViewData();
            this.BindCartLinks();

            var serviceClient = new CartService();

            //shipping information
            var shippingInfo = serviceClient.GetShippingInfo();
            this.BindShippingItems(shippingInfo.Shipping);

            var info = serviceClient.GetPaymentInfo();
            this.BindPaymentItmes(info.Payment);

            return View(info);
        }

        [HttpPost]
        [Authorize(Roles = "Customer")]
        public ActionResult Payment(ShippingInfo shippingInfo, PaymentInfo paymentInfo)
        {
            //cart.Payment();
            var serviceClient = new CartService();

            serviceClient.UpdateShippingAndPaymentMethod(shippingInfo.Shipping, paymentInfo.Payment, paymentInfo.Coupon);

            return this.Redirect(this.Url.Action<CartController>(m => m.Pay()));
        }

        #endregion

        #region Pay

        [Authorize(Roles = "Customer")]
        public ActionResult Pay()
        {
            this.BindViewData();
            this.BindCartLinks();
            this.BindCartItems();

            var serviceClient = new CartService();
            this.ViewBag.ShippingInfo = serviceClient.GetShippingInfo();
            this.ViewBag.PaymentInfo = serviceClient.GetPaymentInfo();

            return View(this.OpenCart());

        }

        [HttpPost]
        [Authorize(Roles = "Customer")]
        public ActionResult Pay(string remark)
        {
            var thankYouPageUrl = Url.RouteUrl("web_account_order_thankyou", null, "http", this.Request.Url.Host);

            var serviceClient = new CartService();
            try
            {
                var order = serviceClient.Purchase(remark, thankYouPageUrl);
            }
            catch (Exception e)
            {
                return Redirect(this.Url.Action("Error", "Account", new { Message = e.Message }));
            }
            return this.Redirect(this.Url.Action<HomeController>(m => m.Index()));
        }

        #endregion

        #region Private Methods

        void BindCartItems()
        {
            var cart = this.OpenCart();

            this.ViewBag.CartItems = cart.Items
                .Select(i => new
                {
                    Discount = i.Discount.ToString("c"),
                    i.Id,
                    i.Image,
                    i.ProductId,
                    i.ProductName,
                    ProductUrl = this.Url.Action<ProductController>(m => m.View(i.ProductId, null)),
                    i.Quantity,
                    i.SaleItemId,
                    SubTotal = i.SubTotal.ToString("c"),
                    TaxCost = i.TaxCost.ToString("c"),
                    Total = (i.SubTotal - i.Discount).ToString("c"),
                    UnitPrice = i.UnitPrice.ToString("c"),
                    Sku = i.Sku,
                    RemoveUrl = this.Url.Action<CartController>(m => m.Remove(i.Id, i.Quantity)),
                    MinusUrl = this.Url.Action<CartController>(m => m.Remove(i.Id, 1)),
                    PlusUrl = this.Url.Action<CartController>(m => m.Add(i.SaleItemId, 1))
                });
        }

        void BindAdresses()
        {
            var service = new CartService();
            this.ViewBag.Addresses = service.GetCurrentAddresses();
        }

        void BindShippingItems(int id = int.MinValue)
        {
            var service = new ItemService();

            this.ViewBag.ShippingItems = service.GetShippings(id);
        }

        void BindCountryItems(string name = null)
        {
            var service = new ItemService();
            var cart = this.OpenCart();
            this.ViewBag.CountryItems = service.GetCountries(name);
        }

        void BindShippingCountryItems(string name = null)
        {
            var service = new ItemService();
            var cart = this.OpenCart();
            this.ViewBag.ShippingCountryItems = service.GetCountries(name);
        }

        void BindPaymentCountryItems(string name = null)
        {
            var service = new ItemService();
            var cart = this.OpenCart();
            this.ViewBag.PaymentCountryItems = service.GetCountries(name);
        }

        void BindPaymentItmes(string name = null)
        {
            var service = new ItemService();

            this.ViewBag.PaymentItems = service.GetPayments(name);
        }

        void BindCartLinks()
        {
            this.ViewBag.CartLinks = new
            {
                Back = this.Url.Action<HomeController>(m => m.Index()),
                Index = this.Url.Action<CartController>(m => m.Index()),
                Checkout = this.Url.Action<CartController>(m => m.Checkout()),
                Payment = this.Url.Action<CartController>(m => m.Payment()),
                Pay = this.Url.Action<CartController>(m => m.Pay())
            };
        }

        #endregion
    }
}

